package com.cjh.mybatis07.session;


import com.cjh.mybatis07.bind.MapperRegistry;
import com.cjh.mybatis07.datasource.druid.DruidDataSourceFactory;
import com.cjh.mybatis07.datasource.pooled.PooledDataSourceFactory;
import com.cjh.mybatis07.datasource.unpooled.UnpooledDataSourceFactory;
import com.cjh.mybatis07.executor.Executor;
import com.cjh.mybatis07.executor.SimpleExecutor;
import com.cjh.mybatis07.executor.resultset.DefaultResultSetHandler;
import com.cjh.mybatis07.executor.resultset.ResultSetHandler;
import com.cjh.mybatis07.executor.statement.PrepareStatementHandler;
import com.cjh.mybatis07.executor.statement.StatementHandler;
import com.cjh.mybatis07.mapping.BoundSql;
import com.cjh.mybatis07.mapping.Environment;
import com.cjh.mybatis07.mapping.MappedStatement;
import com.cjh.mybatis07.transaction.Transaction;
import com.cjh.mybatis07.transaction.jdbc.JdbcTransactionFactory;
import com.cjh.mybatis07.type.TypeAliasRegistry;
import lombok.Getter;
import lombok.Setter;

import java.util.HashMap;
import java.util.Map;

/**
 * @Descripton 配置类
 * @Author cjh
 * @Date 2023/5/26 11:10
 */
public class Configuration {
    /**
     * //    环境
     */
    @Getter
    @Setter
    protected Environment environment;

    /**
     * 类型别名注册机
     */
    @Getter
    protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();

    public Configuration() {
        typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
        typeAliasRegistry.registerAlias("DRUID", DruidDataSourceFactory.class);
        typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
        typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
    }

    /**
     * 映射注册机
     */
    protected MapperRegistry mapperRegistry = new MapperRegistry(this);
    /**
     * 映射语句  存在map中
     */
    protected final Map<String, MappedStatement> mappedStatements = new HashMap<>();

    public void addMappers(String packageName) {
        mapperRegistry.addMappers(packageName);
    }

    public <T> void addMapper(Class<T> type) {
        mapperRegistry.addMapper(type);
    }

    public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
        return mapperRegistry.getMapper(type, sqlSession);
    }

    public boolean hasMapper(Class<?> type) {
        return mapperRegistry.hasMapper(type);
    }

    public void addMappedStatement(MappedStatement mappedStatement) {
        mappedStatements.put(mappedStatement.getId(), mappedStatement);

    }

    public MappedStatement getMappedStatement(String id) {
        return mappedStatements.get(id);
    }

    /**
     * 创建结果集处理器
     * @param executor
     * @param mappedStatement
     * @param boundSql
     * @return
     */
    public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, BoundSql boundSql){
        return new DefaultResultSetHandler(executor, mappedStatement, boundSql);
    }

    /**
     * 生产执行器
     * @param transaction
     * @return
     */
    public Executor newExecutor(Transaction transaction){
        return new SimpleExecutor(this,transaction);
    }

    public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement
            , Object parameter, ResultHandler resultHandler, BoundSql boundSql){
        return new PrepareStatementHandler(executor,mappedStatement,parameter,resultHandler,boundSql);
    }


}
